package net.jueb.majong.script.center.http;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import net.jueb.majong.core.net.NetConnection;
import net.jueb.majong.core.net.handlerImpl.NetConntectionAdapter;
import net.jueb.majong.script.center.AbstractCenterBaseScript;
import net.jueb.util4j.net.JConnection;
import net.jueb.util4j.net.nettyImpl.NettyConnection;

public abstract class AbstractHttpScript extends AbstractCenterBaseScript implements IHttpScript{
	
	protected final Logger _log=LoggerFactory.getLogger(getClass());

	@Override
	public void action() {
		
	}
	protected NetConnection conn;
	@Override
	public void handleRequest(Request request) {
		HttpRequest httpRequest=(HttpRequest) request.getContent();
		this.conn=request.getConnection();
		if(hasLimitIp(conn)){
			_log.error("ip is limited:" + this.conn.getIP());
			conn.close();
			ReferenceCountUtil.release(httpRequest);
			return ;
		}
		try {
			handleRequest(httpRequest);
		} catch (Exception e) {
			conn.close();
		}
		ReferenceCountUtil.release(httpRequest);
	}
	
	protected void response(String response) {
		response(response.getBytes(CharsetUtil.UTF_8));
	}
	
	protected void response(byte[] response) {
		FullHttpResponse  httpResponse= new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(response));
		httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain; charset=UTF-8");
		if(conn instanceof NetConntectionAdapter)
		{
			NetConntectionAdapter adapter=(NetConntectionAdapter)conn;
			JConnection channel=adapter.getChannel();
			if(channel instanceof NettyConnection)
			{
				NettyConnection c=(NettyConnection)adapter.getChannel();
				c.getChannel().writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);
				return ;
			}
		}
		conn.sendMessage(httpResponse);
		conn.close();
	}
	
	protected Map<String,String> getRequestArgs(HttpRequest msg) {
		Map<String,String> args=new HashMap<>();
		QueryStringDecoder decode=new QueryStringDecoder(msg.uri());
		if(msg.method()==HttpMethod.POST)
		{
			if(msg instanceof FullHttpRequest)
			{
				HttpPostRequestDecoder d=new HttpPostRequestDecoder(msg);
				for(InterfaceHttpData data:d.getBodyHttpDatas())
				{
					if(data.getHttpDataType()==HttpDataType.Attribute)
					{
						Attribute idata=(Attribute)data;
						try {
							args.put(data.getName(),idata.getValue());
						} catch (IOException e) {
							_log.error(e.getMessage(),e);
						}
					}
				}
			}
		}else
		{
			for(Entry<String, List<String>> e:decode.parameters().entrySet())
			{
				args.put(e.getKey(), e.getValue().get(0));
			}
		}
		return args;
	}
	
	/**
	 * 是否IP限制
	 * @param conn
	 * @return
	 */
	private boolean hasLimitIp (NetConnection conn) {
		String ip = conn.getIP();
		List<String> iplist=new ArrayList<>(Arrays.asList(
				"115.231.101.140",
				"115.231.101.139",
				"118.122.119.18",
				"192.168.*.*",
				"127.0.0.1"
				));
		for(String str:iplist)
		{
			if(ip.matches(str))
			{
				return false;
			}
		}
		return true;
	}
	
	protected void responseMsg(int code) {
		responseMsg(code, "");
	}
	
	protected void responseMsg(int code, String msg) {
		responseMsg(code, msg, new JsonObject());
	}
	
	protected void responseMsg(int code, String msg,JsonElement content) {
		JsonObject jsonObject = new JsonObject();
		jsonObject.addProperty("code", code);
		jsonObject.addProperty("msg", msg);
		jsonObject.add("content", content);
		response(jsonObject.toString());
	}
}